//package com.huishi.config.datasource;
//
//
//
//import com.huishi.annotation.DataSource;
//import org.aspectj.lang.ProceedingJoinPoint;
//import org.aspectj.lang.annotation.Around;
//import org.aspectj.lang.annotation.Aspect;
//import org.aspectj.lang.annotation.Pointcut;
//import org.aspectj.lang.reflect.MethodSignature;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//import org.springframework.core.annotation.AnnotationUtils;
//import org.springframework.core.annotation.Order;
//import org.springframework.stereotype.Component;
//
//import java.util.Objects;
//
///**
// * 这是一个使用Spring AOP和切面的类，
// * 它通过@Aspect注解声明自己是一个切面，
// * 而@Order(1)用于指定切面的执行顺序。
// * 该切面的主要作用是根据@DataSource注解来动态切换数据源。
// */
//@Aspect
//@Order(1)
//@Component
//public class DataSourceAspect
//{
//    protected Logger logger = LoggerFactory.getLogger(getClass());
//
//    // @Pointcut定义了切点，即切面在哪些地方执行。
//    // 这里的切点是所有带有@DataSource注解或者类上带有@DataSource注解的方法。
//    @Pointcut("@annotation(com.huishi.annotation.DataSource)"
//            + "|| @within(com.huishi.annotation.DataSource)")
//    public void dsPointCut()
//    {
//        // dsPointCut()方法：
//        // 这个方法是一个空方法，其主要作用是给@Pointcut注解提供一个命名的切点，使得@Around注解可以引用这个切点。
//        // 给切入点起名dsPointCut
//        // within
//    }
//
//    /**
//     * @Around 注解表示在目标方法执行前后执行一些逻辑。
//     * 在这里，它用于切面织入，即在目标方法执行前切换数据源，在目标方法执行后清理数据源。
//     *
//     * @param point 目标方法，可以理解为目标方法被拦截下来了。
//     * @return 就是目标方法的返回值
//     */
//    @Around("dsPointCut()")
//    public Object around(ProceedingJoinPoint point) throws Throwable
//    {
//        DataSource dataSource = getDataSource(point);
//
//        if (dataSource != null)
//        {
//            DynamicDataSourceContextHolder.setDataSourceType(dataSource.value().name());
//        }
//
//        try
//        {
//            // 继续执行下一个通知或目标方法调用
//            return point.proceed();
//        }
//        finally
//        {
//            // 销毁数据源 在执行方法之后
//            DynamicDataSourceContextHolder.clearDataSourceType();
//        }
//    }
//
//    /**
//     * 获取需要切换的数据源
//     */
//    public DataSource getDataSource(ProceedingJoinPoint point)
//    {
//        // 获取目标方法的签名
//        MethodSignature signature = (MethodSignature) point.getSignature();
//        // 获取目标方法上的DataSource注解
//        DataSource dataSource = AnnotationUtils.findAnnotation(signature.getMethod(), DataSource.class);
//        if (Objects.nonNull(dataSource))
//        {
//            return dataSource;
//        }
//
//        // 获取目标方法类上的DataSource注解
//        return AnnotationUtils.findAnnotation(signature.getDeclaringType(), DataSource.class);
//    }
//}
//
